package com.luobo.pcsdepositmanage.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.luobo.pcsdepositmanage.easyexcel.listener.basic.MultiLineToSingleListener;
import com.luobo.pcsdepositmanage.easyexcel.listener.basic.NoModelDataListener;
import org.apache.poi.ss.formula.functions.T;

import java.io.File;
import java.util.*;
import java.util.function.Consumer;

public class EasyExcelUtils {

    /**
     * 单行内有多条数据，转换成多行数据。
     * @param paraMap
     * @return
     * @throws Exception
     */
    public static List<Map<Integer,Object>> multiLineToSingleEasyExcel(Map<String,Object> paraMap) throws Exception{
        String pathName = null;
        String sheetname = null;
        int headrownum = 0;
        if(paraMap.containsKey("filedir") && paraMap.containsKey("filename") ){
            pathName = (String) paraMap.get("filedir")+"/"+(String) paraMap.get("filename");
        }else{
            throw new UnsupportedOperationException("paraMap缺少filedir或filename，key值");
        }
        if(paraMap.containsKey("sheetname")){
            sheetname = (String)paraMap.get("sheetname");
        }else{
            throw new UnsupportedOperationException("paraMap缺少sheetname，key值");
        }
        if(paraMap.containsKey("headrownum")){
            headrownum = (Integer) paraMap.get("headrownum");
        }

        MultiLineToSingleListener multiLineToSingleListener = new MultiLineToSingleListener();
        ExcelReader excelReader = null;
        try {
            excelReader = EasyExcel.read(pathName,multiLineToSingleListener).headRowNumber(headrownum).build();
            ReadSheet readSheet = EasyExcel.readSheet(sheetname).build();
            excelReader.read(readSheet);
        } finally {
            if (excelReader != null) {
                // 这里千万别忘记关闭，读的时候会创建临时文件，到时磁盘会崩的
                excelReader.finish();
            }
        }
        List<Map<Integer,Object>> mapList = multiLineToSingleListener.getList();

        return mapList;
    }


    /**
     * 根据paraMap参数，读取Excel,转换成List<Map<Integer,Object>> 返回。
     * @param paraMap
     * @return
     * @throws Exception
     */
    public static List<Map<Integer,Object>> noModelReadEasyExcel(Map<String,Object> paraMap) throws Exception{
        String pathName = null;
        Object tempObject = null;
        int headrownum = 0;
        if(paraMap.containsKey("filedir") && paraMap.containsKey("filename") ){
            pathName = (String) paraMap.get("filedir")+ File.separator+(String) paraMap.get("filename");
        }else{
            throw new UnsupportedOperationException("paraMap缺少filedir或filename，key值");
        }
        if(paraMap.containsKey("sheetname")){
            tempObject = paraMap.get("sheetname");
        }else{
            throw new UnsupportedOperationException("paraMap缺少sheetname，key值");
        }
        if(paraMap.containsKey("headrownum")){
            headrownum = (Integer) paraMap.get("headrownum");
        }

        NoModelDataListener noModelDataListener = new NoModelDataListener();
        ExcelReader excelReader = null;
        try {
            excelReader = EasyExcel.read(pathName,noModelDataListener).headRowNumber(headrownum).build();
            ReadSheet readSheet = null;
            if(tempObject instanceof String){
                String sheetname = (String) tempObject;
                readSheet = EasyExcel.readSheet(sheetname).build();
            }else if(tempObject instanceof  Integer){
                int pageNum = (Integer) tempObject;
                readSheet = EasyExcel.readSheet(pageNum).build();

            }
            excelReader.read(readSheet);
        } finally {
            if (excelReader != null) {
                // 这里千万别忘记关闭，读的时候会创建临时文件，到时磁盘会崩的
                excelReader.finish();
            }
        }
        List<Map<Integer,Object>> mapList = noModelDataListener.getList();

        return mapList;
    }



    public static void readForEasyExcel(Map<String, Object> map) throws Exception {
        // 写法2：
        String filedir = (String) map.get("filedir");
        String filename = (String) map.get("filename");
        String pathName = filedir + File.separator + filename;
        String sheetname = (String) map.get("sheetname");

        int headrownum = 1;
        if(map.containsKey("headrownum")){
            headrownum = (Integer) map.get("headrownum");
        }

        Class clazz = (Class) map.get("clazz");
        AnalysisEventListener listener = (AnalysisEventListener) map.get("listener");
        ExcelReader excelReader = null;
        try {
            excelReader = EasyExcel.read(pathName, clazz, listener).build();

            ReadSheet readSheet = EasyExcel.readSheet(sheetname).headRowNumber(headrownum).build();
            excelReader.read(readSheet);

        } finally {
            if (excelReader != null) {
                // 这里千万别忘记关闭，读的时候会创建临时文件，到时磁盘会崩的
                excelReader.finish();
            }
        }

    }


    public static void  writeToEasyExcel(Map<String, Object> map, List<T> objectList) throws Exception {
        // 写法2：
        String filedir = (String) map.get("filedir");
        String filename = (String) map.get("filename");
        String pathName = filedir + File.separator + filename;
        String sheetname = (String) map.get("sheetname");

        Class clazz = (Class) map.get("clazz");

        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(pathName, clazz).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetname).build();
            excelWriter.write(objectList, writeSheet);

        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }

    public static void readForEasyExcelConsumer(Map<String, Object> map) throws Exception {
        // 写法2：
        String filedir = (String) map.get("filedir");
        String filename = (String) map.get("filename");
        String pathName = filedir + File.separator + filename;
        String sheetname = (String) map.get("sheetname");
        int pageSize = (Integer)map.get("pageSize");
        Class clazz = (Class) map.get("clazz");
//        AnalysisEventListener listener = (AnalysisEventListener) map.get("listener");
        ExcelReader excelReader = null;
        try {
            ConsumerUtil<List<T>> consumer = pageList->{System.out.println(pageList.size());
                System.out.println(pageList); return pageList;};
            excelReader = ExcelUtil.read(pathName, clazz, pageSize,consumer).build();

            ReadSheet readSheet = EasyExcel.readSheet(sheetname).build();
            excelReader.read(readSheet);

        } finally {
            if (excelReader != null) {
                // 这里千万别忘记关闭，读的时候会创建临时文件，到时磁盘会崩的
                excelReader.finish();
            }
        }

    }


    public static void  writeToEasyExcelConsumer(Map<String, Object> map, List<T> objectList) throws Exception {
        // 写法2：
        String filedir = (String) map.get("filedir");
        String filename = (String) map.get("filename");
        String pathName = filedir + File.separator + filename;
        String sheetname = (String) map.get("sheetname");

        Class clazz = (Class) map.get("clazz");

        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(pathName, clazz).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetname).build();
            excelWriter.write(objectList, writeSheet);

        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }


    public static void  writeToEasyExcelNoMoudle(Map<String, Object> map, List<List<Object>> mapList) throws Exception {
        // 写法2：
        String filedir = (String) map.get("filedir");
        String filename = (String) map.get("filename");
        String pathName = filedir + File.separator + filename;
        String sheetname = (String) map.get("sheetname");

//        Class clazz = (Class) map.get("clazz");

        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(pathName).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetname).build();
            excelWriter.write(mapList, writeSheet);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }

    public static List<Map<Integer,Object>> analyseAddColumn(List<Map<Integer,Object>> mapList,int column){

        List<Map<Integer,Object>> resultMapList = new ArrayList<>();

        for (Map<Integer,Object> map:
             mapList) {

            int columnAdd = map.keySet().size()+1;
            Map<Integer,Object> resultMap = new HashMap<>(map);

            String dealData = (String)map.get(column);
            String resultData = null;
            resultData = dealData.replaceAll("/","|").replaceAll(",","|").replaceAll("/","|").replaceAll("\\s+","|").replaceAll("[\\t\\n\\r]","|");
            String[] resultArray = resultData.split("\\|");
            Set<String> stringSet = new HashSet<>();
            Collections.addAll(stringSet,resultArray);
            String resultString = String.join("|",stringSet);

            resultMap.put(columnAdd,resultString);
            resultMapList.add(resultMap);
        }


        return resultMapList;
    }


    /**
     * 将List<Map<Integer,Object>>  转换成col<row> List<List<Object>>  方便存储回Excel文件。
     * @param mapList
     * @return
     */
    public static List<List<Object>> convertMapToListForCols(List<Map<Integer,Object>> mapList){
        List<List<Object>> lists = new ArrayList<>();
            for (int i = (Integer) getMinKey(mapList.get(0));i < mapList.get(0).keySet().size();i ++) {
                List<Object> objectList = new ArrayList<Object>();
                for (Map<Integer,Object> map: mapList) {
                    objectList.add(map.get(i));
                }
                lists.add(objectList);
            }
        return lists;

    }
    /**
     * 将List<Map<Integer,Object>>  转换成row<col>  List<List<Object>>  方便存储回Excel文件。
     * @param mapList
     * @return
     */
    public static List<List<Object>> convertMapToListForRows(List<Map<Integer, Object>> mapList){

        List<List<Object>> resultlists = new ArrayList<>();
        for (Map<Integer, Object> map:
        mapList){
            List<Object> list = new ArrayList<Object>(map.values());
            resultlists.add(list);
        }
        return resultlists;
    }

    public static Object getMinKey(Map<Integer, Object> map) {
        if (map == null) {
            return null;
        }
        Set<Integer> set = map.keySet();
        Object[] obj = set.toArray();
        Arrays.sort(obj);
        return obj[0];
    }
}
